/*
 * This file is part of JGAP.
 *
 * JGAP offers a dual license model containing the LGPL as well as the MPL.
 *
 * For licensing information please see the file license.txt included with JGAP
 * or have a look at the top of class org.jgap.Chromosome which representatively
 * includes the JGAP license policy applicable for any file delivered with JGAP.
 */
package examples.gp;

import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.*;
import org.jgap.*;
import org.jgap.gp.*;
import org.jgap.gp.function.*;
import org.jgap.gp.impl.*;
import org.jgap.gp.terminal.*;

/**
 * Example demonstrating Genetic Programming (GP) capabilities of JGAP.
 * Also demonstrates usage of ADF's.<br>
 * The problem is to find a formula for a given truth table (X/Y-pairs).
 * <p>
 * <ul>
 * <li>The setup of the GP is done in method main and specifically in method
 * create()</li>
 * <li>The problem solving process is started via gp.evolve(800) in the main
 * method, with 800 the maximum number of evolutions to take place.
 * <li>The evaluation of the evolved formula is done in fitness function
 * FormulaFitnessFunction, which is implemented in this class, StockProblem
 * </ul>
 * <br>
 * For details, please see the mentioned methods and the fitness function.
 * <p>
 * @author Klaus Meffert
 * @since 3.0
 */
public class StockProblem
    extends GPProblem {
  /** String containing the CVS revision. Read out via reflection!*/
  private final static String CVS_REVISION = "$Revision: 1.25 $";

  public static Variable vx1,vx2,vx3,vx4,/*vx5,vx6,*/vx200,vx201,vx202,vx203,vx204;

  //public static Variable vx194,vx195,vx196,vx197,vx198,vx199,vx200,vx201,vx202,vx203,vx204;
  //static Variable vx5,vx6,vx7,vx8,vx9,vx10,vx11,vx12,vx13,vx14,vx15,vx16,vx17,vx18,vx19,vx20,vx21,vx22,vx23,vx24,vx25,vx26,vx27,vx28,vx29,vx30,vx31,vx32,vx33,vx34,vx35,vx36,vx37,vx38,vx39,vx40,vx41,vx42,vx43,vx44,vx45,vx46,vx47,vx48,vx49,vx50,vx51,vx52,vx53,vx54,vx55,vx56,vx57,vx58,vx59,vx60,vx61,vx62,vx63,vx64,vx65,vx66,vx67,vx68,vx69,vx70,vx71,vx72,vx73,vx74,vx75,vx76,vx77,vx78,vx79,vx80,vx81,vx82,vx83,vx84,vx85,vx86,vx87,vx88,vx89,vx90,vx91,vx92,vx93,vx94,vx95,vx96,vx97,vx98,vx99,vx100,vx101,vx102,vx103,vx104,vx105,vx106,vx107,vx108,vx109,vx110,vx111,vx112,vx113,vx114,vx115,vx116,vx117,vx118,vx119,vx120,vx121,vx122,vx123,vx124,vx125,vx126,vx127,vx128,vx129,vx130,vx131,vx132,vx133,vx134,vx135,vx136,vx137,vx138,vx139,vx140,vx141,vx142,vx143,vx144,vx145,vx146,vx147,vx148,vx149,vx150,vx151,vx152,vx153,vx154,vx155,vx156,vx157,vx158,vx159,vx160,vx161,vx162,vx163,vx164,vx165,vx166,vx167,vx168,vx169,vx170,vx171,vx172,vx173,vx174,vx175,vx176,vx177,vx178,vx179,vx180,vx181,vx182,vx183,vx184,vx185,vx186,vx187,vx188,vx189,vx190,vx191,vx192,vx193,vx194,vx195,vx196,vx197,vx198,vx199,vx200,vx201,vx202,vx203,vx204;
  public static ArrayList<Variable> vars = new ArrayList<Variable>();
  
  //protected static double[] x = new double[20];

  //protected static double[] y = new double[20];

  public static ArrayList<Stock> stocks;
  public static int days;
  public static String modelfile;
  public StockProblem(GPConfiguration a_conf)
      throws InvalidConfigurationException {
    super(a_conf);
  }

  /**
   * This method is used for setting up the commands and terminals that can be
   * used to solve the problem.
   * In this example an ADF (an automatically defined function) is used for
   * demonstration purpuses. Using an ADF is optional. If you want to use one,
   * care about the places marked with "ADF-relevant:" below. If you do not want
   * to use an ADF, please remove the below places (and reduce the outer size of
   * the arrays "types", "argTypes" and "nodeSets" to one).
   * Please notice, that the variables types, argTypes and nodeSets correspond
   * to each other: they have the same number of elements and the element at
   * the i'th index of each variable corresponds to the i'th index of the other
   * variables!
   *
   * @return GPGenotype
   * @throws InvalidConfigurationException
   */
  public GPGenotype create()
      throws InvalidConfigurationException {
    GPConfiguration conf = getGPConfiguration();
    // At first, we define the return type of the GP program.
    // ------------------------------------------------------
    Class[] types = {
        // Return type of result-producing chromosome
        CommandGene.DoubleClass
        // ADF-relevant:
        // Return type of ADF 1
       // CommandGene.DoubleClass
        };
    // Then, we define the arguments of the GP parts. Normally, only for ADF's
    // there is a specification here, otherwise it is empty as in first case.
    // -----------------------------------------------------------------------
    Class[][] argTypes = {
        // Arguments of result-producing chromosome: none
        {}
        // ADF-relevant:
        // Arguments of ADF1: all 3 are double
       // {CommandGene.DoubleClass, CommandGene.DoubleClass, CommandGene.DoubleClass}
    };
    // Next, we define the set of available GP commands and terminals to use.
    // Please see package org.jgap.gp.function and org.jgap.gp.terminal
    // You can easily add commands and terminals of your own.
    // ----------------------------------------------------------------------
   
   // CommandGene[][] nodeSets;// = new CommandGene[1][10];
    CommandGene[][] nodeSets = { {
    	vx1=Variable.create(conf, "X1", CommandGene.DoubleClass),
    	vx2=Variable.create(conf, "X2", CommandGene.DoubleClass),
    	vx3=Variable.create(conf, "X3", CommandGene.DoubleClass),
    	vx4=Variable.create(conf, "X4", CommandGene.DoubleClass),

    	
    	/*vx5=Variable.create(conf, "X5", CommandGene.DoubleClass),
    	vx6=Variable.create(conf, "X6", CommandGene.DoubleClass),
    	
    	vx7=Variable.create(conf, "X7", CommandGene.DoubleClass),
    	vx8=Variable.create(conf, "X8", CommandGene.DoubleClass),
    	vx9=Variable.create(conf, "X9", CommandGene.DoubleClass),
    	vx10=Variable.create(conf, "X10", CommandGene.DoubleClass),
    	vx11=Variable.create(conf, "X11", CommandGene.DoubleClass),
    	vx12=Variable.create(conf, "X12", CommandGene.DoubleClass),
    	vx13=Variable.create(conf, "X13", CommandGene.DoubleClass),
    	vx14=Variable.create(conf, "X14", CommandGene.DoubleClass),
    	vx15=Variable.create(conf, "X15", CommandGene.DoubleClass),
    	vx16=Variable.create(conf, "X16", CommandGene.DoubleClass),
    	vx17=Variable.create(conf, "X17", CommandGene.DoubleClass),
    	vx18=Variable.create(conf, "X18", CommandGene.DoubleClass),
    	vx19=Variable.create(conf, "X19", CommandGene.DoubleClass),
    	vx20=Variable.create(conf, "X20", CommandGene.DoubleClass),
    	vx21=Variable.create(conf, "X21", CommandGene.DoubleClass),
    	vx22=Variable.create(conf, "X22", CommandGene.DoubleClass),
    	vx23=Variable.create(conf, "X23", CommandGene.DoubleClass),
    	vx24=Variable.create(conf, "X24", CommandGene.DoubleClass),
    	vx25=Variable.create(conf, "X25", CommandGene.DoubleClass),
    	vx26=Variable.create(conf, "X26", CommandGene.DoubleClass),
    	vx27=Variable.create(conf, "X27", CommandGene.DoubleClass),
    	vx28=Variable.create(conf, "X28", CommandGene.DoubleClass),
    	vx29=Variable.create(conf, "X29", CommandGene.DoubleClass),
    	vx30=Variable.create(conf, "X30", CommandGene.DoubleClass),
    	vx31=Variable.create(conf, "X31", CommandGene.DoubleClass),
    	vx32=Variable.create(conf, "X32", CommandGene.DoubleClass),
    	vx33=Variable.create(conf, "X33", CommandGene.DoubleClass),
    	vx34=Variable.create(conf, "X34", CommandGene.DoubleClass),
    	vx35=Variable.create(conf, "X35", CommandGene.DoubleClass),
    	vx36=Variable.create(conf, "X36", CommandGene.DoubleClass),
    	vx37=Variable.create(conf, "X37", CommandGene.DoubleClass),
    	vx38=Variable.create(conf, "X38", CommandGene.DoubleClass),
    	vx39=Variable.create(conf, "X39", CommandGene.DoubleClass),
    	vx40=Variable.create(conf, "X40", CommandGene.DoubleClass),
    	vx41=Variable.create(conf, "X41", CommandGene.DoubleClass),
    	vx42=Variable.create(conf, "X42", CommandGene.DoubleClass),
    	vx43=Variable.create(conf, "X43", CommandGene.DoubleClass),
    	vx44=Variable.create(conf, "X44", CommandGene.DoubleClass),
    	vx45=Variable.create(conf, "X45", CommandGene.DoubleClass),
    	vx46=Variable.create(conf, "X46", CommandGene.DoubleClass),
    	vx47=Variable.create(conf, "X47", CommandGene.DoubleClass),
    	vx48=Variable.create(conf, "X48", CommandGene.DoubleClass),
    	vx49=Variable.create(conf, "X49", CommandGene.DoubleClass),
    	vx50=Variable.create(conf, "X50", CommandGene.DoubleClass),
    	vx51=Variable.create(conf, "X51", CommandGene.DoubleClass),
    	vx52=Variable.create(conf, "X52", CommandGene.DoubleClass),
    	vx53=Variable.create(conf, "X53", CommandGene.DoubleClass),
    	vx54=Variable.create(conf, "X54", CommandGene.DoubleClass),
    	vx55=Variable.create(conf, "X55", CommandGene.DoubleClass),
    	vx56=Variable.create(conf, "X56", CommandGene.DoubleClass),
    	vx57=Variable.create(conf, "X57", CommandGene.DoubleClass),
    	vx58=Variable.create(conf, "X58", CommandGene.DoubleClass),
    	vx59=Variable.create(conf, "X59", CommandGene.DoubleClass),
    	vx60=Variable.create(conf, "X60", CommandGene.DoubleClass),
    	vx61=Variable.create(conf, "X61", CommandGene.DoubleClass),
    	vx62=Variable.create(conf, "X62", CommandGene.DoubleClass),
    	vx63=Variable.create(conf, "X63", CommandGene.DoubleClass),
    	vx64=Variable.create(conf, "X64", CommandGene.DoubleClass),
    	vx65=Variable.create(conf, "X65", CommandGene.DoubleClass),
    	vx66=Variable.create(conf, "X66", CommandGene.DoubleClass),
    	vx67=Variable.create(conf, "X67", CommandGene.DoubleClass),
    	vx68=Variable.create(conf, "X68", CommandGene.DoubleClass),
    	vx69=Variable.create(conf, "X69", CommandGene.DoubleClass),
    	vx70=Variable.create(conf, "X70", CommandGene.DoubleClass),
    	vx71=Variable.create(conf, "X71", CommandGene.DoubleClass),
    	vx72=Variable.create(conf, "X72", CommandGene.DoubleClass),
    	vx73=Variable.create(conf, "X73", CommandGene.DoubleClass),
    	vx74=Variable.create(conf, "X74", CommandGene.DoubleClass),
    	vx75=Variable.create(conf, "X75", CommandGene.DoubleClass),
    	vx76=Variable.create(conf, "X76", CommandGene.DoubleClass),
    	vx77=Variable.create(conf, "X77", CommandGene.DoubleClass),
    	vx78=Variable.create(conf, "X78", CommandGene.DoubleClass),
    	vx79=Variable.create(conf, "X79", CommandGene.DoubleClass),
    	vx80=Variable.create(conf, "X80", CommandGene.DoubleClass),
    	vx81=Variable.create(conf, "X81", CommandGene.DoubleClass),
    	vx82=Variable.create(conf, "X82", CommandGene.DoubleClass),
    	vx83=Variable.create(conf, "X83", CommandGene.DoubleClass),
    	vx84=Variable.create(conf, "X84", CommandGene.DoubleClass),
    	vx85=Variable.create(conf, "X85", CommandGene.DoubleClass),
    	vx86=Variable.create(conf, "X86", CommandGene.DoubleClass),
    	vx87=Variable.create(conf, "X87", CommandGene.DoubleClass),
    	vx88=Variable.create(conf, "X88", CommandGene.DoubleClass),
    	vx89=Variable.create(conf, "X89", CommandGene.DoubleClass),
    	vx90=Variable.create(conf, "X90", CommandGene.DoubleClass),
    	vx91=Variable.create(conf, "X91", CommandGene.DoubleClass),
    	vx92=Variable.create(conf, "X92", CommandGene.DoubleClass),
    	vx93=Variable.create(conf, "X93", CommandGene.DoubleClass),
    	vx94=Variable.create(conf, "X94", CommandGene.DoubleClass),
    	vx95=Variable.create(conf, "X95", CommandGene.DoubleClass),
    	vx96=Variable.create(conf, "X96", CommandGene.DoubleClass),
    	vx97=Variable.create(conf, "X97", CommandGene.DoubleClass),
    	vx98=Variable.create(conf, "X98", CommandGene.DoubleClass),
    	vx99=Variable.create(conf, "X99", CommandGene.DoubleClass),
    	vx100=Variable.create(conf, "X100", CommandGene.DoubleClass),
    	vx101=Variable.create(conf, "X101", CommandGene.DoubleClass),
    	vx102=Variable.create(conf, "X102", CommandGene.DoubleClass),
    	vx103=Variable.create(conf, "X103", CommandGene.DoubleClass),
    	vx104=Variable.create(conf, "X104", CommandGene.DoubleClass),
    	vx105=Variable.create(conf, "X105", CommandGene.DoubleClass),
    	vx106=Variable.create(conf, "X106", CommandGene.DoubleClass),
    	vx107=Variable.create(conf, "X107", CommandGene.DoubleClass),
    	vx108=Variable.create(conf, "X108", CommandGene.DoubleClass),
    	vx109=Variable.create(conf, "X109", CommandGene.DoubleClass),
    	vx110=Variable.create(conf, "X110", CommandGene.DoubleClass),
    	vx111=Variable.create(conf, "X111", CommandGene.DoubleClass),
    	vx112=Variable.create(conf, "X112", CommandGene.DoubleClass),
    	vx113=Variable.create(conf, "X113", CommandGene.DoubleClass),
    	vx114=Variable.create(conf, "X114", CommandGene.DoubleClass),
    	vx115=Variable.create(conf, "X115", CommandGene.DoubleClass),
    	vx116=Variable.create(conf, "X116", CommandGene.DoubleClass),
    	vx117=Variable.create(conf, "X117", CommandGene.DoubleClass),
    	vx118=Variable.create(conf, "X118", CommandGene.DoubleClass),
    	vx119=Variable.create(conf, "X119", CommandGene.DoubleClass),
    	vx120=Variable.create(conf, "X120", CommandGene.DoubleClass),
    	vx121=Variable.create(conf, "X121", CommandGene.DoubleClass),
    	vx122=Variable.create(conf, "X122", CommandGene.DoubleClass),
    	vx123=Variable.create(conf, "X123", CommandGene.DoubleClass),
    	vx124=Variable.create(conf, "X124", CommandGene.DoubleClass),
    	vx125=Variable.create(conf, "X125", CommandGene.DoubleClass),
    	vx126=Variable.create(conf, "X126", CommandGene.DoubleClass),
    	vx127=Variable.create(conf, "X127", CommandGene.DoubleClass),
    	vx128=Variable.create(conf, "X128", CommandGene.DoubleClass),
    	vx129=Variable.create(conf, "X129", CommandGene.DoubleClass),
    	vx130=Variable.create(conf, "X130", CommandGene.DoubleClass),
    	vx131=Variable.create(conf, "X131", CommandGene.DoubleClass),
    	vx132=Variable.create(conf, "X132", CommandGene.DoubleClass),
    	vx133=Variable.create(conf, "X133", CommandGene.DoubleClass),
    	vx134=Variable.create(conf, "X134", CommandGene.DoubleClass),
    	vx135=Variable.create(conf, "X135", CommandGene.DoubleClass),
    	vx136=Variable.create(conf, "X136", CommandGene.DoubleClass),
    	vx137=Variable.create(conf, "X137", CommandGene.DoubleClass),
    	vx138=Variable.create(conf, "X138", CommandGene.DoubleClass),
    	vx139=Variable.create(conf, "X139", CommandGene.DoubleClass),
    	vx140=Variable.create(conf, "X140", CommandGene.DoubleClass),
    	vx141=Variable.create(conf, "X141", CommandGene.DoubleClass),
    	vx142=Variable.create(conf, "X142", CommandGene.DoubleClass),
    	vx143=Variable.create(conf, "X143", CommandGene.DoubleClass),
    	vx144=Variable.create(conf, "X144", CommandGene.DoubleClass),
    	vx145=Variable.create(conf, "X145", CommandGene.DoubleClass),
    	vx146=Variable.create(conf, "X146", CommandGene.DoubleClass),
    	vx147=Variable.create(conf, "X147", CommandGene.DoubleClass),
    	vx148=Variable.create(conf, "X148", CommandGene.DoubleClass),
    	vx149=Variable.create(conf, "X149", CommandGene.DoubleClass),
    	vx150=Variable.create(conf, "X150", CommandGene.DoubleClass),
    	vx151=Variable.create(conf, "X151", CommandGene.DoubleClass),
    	vx152=Variable.create(conf, "X152", CommandGene.DoubleClass),
    	vx153=Variable.create(conf, "X153", CommandGene.DoubleClass),
    	vx154=Variable.create(conf, "X154", CommandGene.DoubleClass),
    	vx155=Variable.create(conf, "X155", CommandGene.DoubleClass),
    	vx156=Variable.create(conf, "X156", CommandGene.DoubleClass),
    	vx157=Variable.create(conf, "X157", CommandGene.DoubleClass),
    	vx158=Variable.create(conf, "X158", CommandGene.DoubleClass),
    	vx159=Variable.create(conf, "X159", CommandGene.DoubleClass),
    	vx160=Variable.create(conf, "X160", CommandGene.DoubleClass),
    	vx161=Variable.create(conf, "X161", CommandGene.DoubleClass),
    	vx162=Variable.create(conf, "X162", CommandGene.DoubleClass),
    	vx163=Variable.create(conf, "X163", CommandGene.DoubleClass),
    	vx164=Variable.create(conf, "X164", CommandGene.DoubleClass),
    	vx165=Variable.create(conf, "X165", CommandGene.DoubleClass),
    	vx166=Variable.create(conf, "X166", CommandGene.DoubleClass),
    	vx167=Variable.create(conf, "X167", CommandGene.DoubleClass),
    	vx168=Variable.create(conf, "X168", CommandGene.DoubleClass),
    	vx169=Variable.create(conf, "X169", CommandGene.DoubleClass),
    	vx170=Variable.create(conf, "X170", CommandGene.DoubleClass),
    	vx171=Variable.create(conf, "X171", CommandGene.DoubleClass),
    	vx172=Variable.create(conf, "X172", CommandGene.DoubleClass),
    	vx173=Variable.create(conf, "X173", CommandGene.DoubleClass),
    	vx174=Variable.create(conf, "X174", CommandGene.DoubleClass),
    	vx175=Variable.create(conf, "X175", CommandGene.DoubleClass),
    	vx176=Variable.create(conf, "X176", CommandGene.DoubleClass),
    	vx177=Variable.create(conf, "X177", CommandGene.DoubleClass),
    	vx178=Variable.create(conf, "X178", CommandGene.DoubleClass),
    	vx179=Variable.create(conf, "X179", CommandGene.DoubleClass),
    	vx180=Variable.create(conf, "X180", CommandGene.DoubleClass),
    	vx181=Variable.create(conf, "X181", CommandGene.DoubleClass),
    	vx182=Variable.create(conf, "X182", CommandGene.DoubleClass),
    	vx183=Variable.create(conf, "X183", CommandGene.DoubleClass),
    	vx184=Variable.create(conf, "X184", CommandGene.DoubleClass),
    	vx185=Variable.create(conf, "X185", CommandGene.DoubleClass),
    	vx186=Variable.create(conf, "X186", CommandGene.DoubleClass),
    	vx187=Variable.create(conf, "X187", CommandGene.DoubleClass),
    	vx188=Variable.create(conf, "X188", CommandGene.DoubleClass),
    	vx189=Variable.create(conf, "X189", CommandGene.DoubleClass),
    	vx190=Variable.create(conf, "X190", CommandGene.DoubleClass),
    	vx191=Variable.create(conf, "X191", CommandGene.DoubleClass),
    	vx192=Variable.create(conf, "X192", CommandGene.DoubleClass),
    	vx193=Variable.create(conf, "X193", CommandGene.DoubleClass),
    	
    	vx194=Variable.create(conf, "X194", CommandGene.DoubleClass),
    	vx195=Variable.create(conf, "X195", CommandGene.DoubleClass),
    	vx196=Variable.create(conf, "X196", CommandGene.DoubleClass),
    	vx197=Variable.create(conf, "X197", CommandGene.DoubleClass),
    	vx198=Variable.create(conf, "X198", CommandGene.DoubleClass),
    	vx199=Variable.create(conf, "X199", CommandGene.DoubleClass),*/
    	vx200=Variable.create(conf, "X200", CommandGene.DoubleClass),
    	vx201=Variable.create(conf, "X201", CommandGene.DoubleClass),
    	vx202=Variable.create(conf, "X202", CommandGene.DoubleClass),
    	vx203=Variable.create(conf, "X203", CommandGene.DoubleClass),
    	vx204=Variable.create(conf, "X204", CommandGene.DoubleClass),
  
    	new Multiply(conf, CommandGene.DoubleClass),
    	new Multiply3(conf, CommandGene.DoubleClass),
        new Divide(conf, CommandGene.DoubleClass),
        new Sine(conf, CommandGene.DoubleClass),
        new Exp(conf, CommandGene.DoubleClass),
        new Subtract(conf, CommandGene.DoubleClass),
        new Pow(conf, CommandGene.DoubleClass),
       
        new Terminal(conf, CommandGene.DoubleClass, 2.0d, 10.0d, true)}
    };
    
   /* for(int i=0;i<1;i++){
    	vars.add(Variable.create(conf, "X"+i, CommandGene.DoubleClass));
    	//if(nodeSets)
    	nodeSets[0][i]=vars.get(i);
    }
    
    nodeSets[0][1]=new Multiply(conf, CommandGene.DoubleClass);
    nodeSets[0][2]=new Multiply3(conf, CommandGene.DoubleClass);
    nodeSets[0][3]=new Divide(conf, CommandGene.DoubleClass);
    nodeSets[0][4]=new Sine(conf, CommandGene.DoubleClass);
    nodeSets[0][5]=new Exp(conf, CommandGene.DoubleClass);
    nodeSets[0][6]=new Subtract(conf, CommandGene.DoubleClass);
    nodeSets[0][7]=new Pow(conf, CommandGene.DoubleClass);
    nodeSets[0][8]=new Terminal(conf, CommandGene.DoubleClass, 2.0d, 10.0d, true);
    */
    /*CommandGene[][] nodeSets = { {
        // We use a variable that can be set in the fitness function.
        // ----------------------------------------------------------
        vx = Variable.create(conf, "X1", CommandGene.DoubleClass),
       
        //vy = Variable.create(conf, "X2", CommandGene.DoubleClass),
        new Multiply(conf, CommandGene.DoubleClass),
        new Multiply3(conf, CommandGene.DoubleClass),
        new Divide(conf, CommandGene.DoubleClass),
        new Sine(conf, CommandGene.DoubleClass),
        new Exp(conf, CommandGene.DoubleClass),
        new Subtract(conf, CommandGene.DoubleClass),
        new Pow(conf, CommandGene.DoubleClass),
        new Terminal(conf, CommandGene.DoubleClass, 2.0d, 10.0d, true),
        // ADF-relevant:
        // Construct a reference to the ADF defined in the second nodeset
        // which has index 1 (second parameter of ADF-constructor).
        // Furthermore, the ADF expects three input parameters (see argTypes[1])
        new ADF(conf, 1 , 3),
    },
        // ADF-relevant:
        // and now the definition of ADF(1)
        {
        new Add3(conf, CommandGene.DoubleClass),
    }
    };*/
    // Here, we define the expected (optimal) output we want to achieve by the
    // function/formula to evolve by the GP.
    // -----------------------------------------------------------------------
    Random random = new Random();
    // Randomly initialize function data (X-Y table) for x^4+x^3+x^2-x
    //---------------------------------------------------------------
    /*for (int i = 0; i < 20; i++) {
      double f = 8.0f * (random.nextdouble() - 0.3f);
      x[i] = new double(f);
      y[i] = f * f * f * f + f * f * f + f * f - f;
      System.out.println(i + ") " + x[i] + "   " + y[i]);
    }*/
    
    // Create genotype with initial population. Here, we use the declarations
    // made above:
    // Use one result-producing chromosome (index 0) with return type double
    // (see types[0]), no argument (argTypes[0]) and several valid commands and
    // terminals (nodeSets[0]). Contained in the node set is an ADF at index 1
    // in the node set (as declared with the second parameter during
    // ADF-construction: new ADF(..,1,..)).
    // The ADF has return type double (types[1]), three input parameters of type
    // double (argTypes[1]) and exactly one function: Add3 (nodeSets[1]).
    // ------------------------------------------------------------------------
    //GPGenotype.r

    
    return GPGenotype.randomInitialGenotype(conf, types, argTypes, nodeSets,
        300, true);
  }

  /**
   * Starts the example.
   *
   * @param args ignored
   * @throws Exception
   *
   * @author Klaus Meffert
   * @since 3.0
   */
  public static void run_alg(ArrayList<Stock> stocks_arr,int numDays,String model)
      throws Exception {

	  modelfile=model;
	  stocks=stocks_arr;
	  days=numDays;
	  System.out.println("num of days:"+days);
	  // Setup the algorithm's parameters.
    // ---------------------------------
    GPConfiguration config = new GPConfiguration();
    // We use a delta fitness evaluator because we compute a defect rate, not
    // a point score!
    // ----------------------------------------------------------------------
    config.setGPFitnessEvaluator(new DeltaGPFitnessEvaluator());
    config.setMaxInitDepth(4);
    config.setPopulationSize(1000);
    config.setMaxCrossoverDepth(8);
    config.setFitnessFunction(new StockProblem.FormulaFitnessFunction());
    config.setStrictProgramCreation(true);
    
    GPProblem problem = new StockProblem(config);
    // Create the genotype of the problem, i.e., define the GP commands and
    // terminals that can be used, and constrain the structure of the GP
    // program.
    // --------------------------------------------------------------------
    GPGenotype gp = problem.create();
    //gp.setVerboseOutput(true);
    
    // Start the computation with maximum 800 evolutions.
    // if a satisfying result is found (fitness value almost 0), JGAP stops
    // earlier automatically.
    // --------------------------------------------------------------------
    gp.evolve(200);
    
    // Print the best solution so far to the console.
    // ----------------------------------------------
    gp.outputSolution(gp.getAllTimeBest());
    System.out.println(gp.getAllTimeBest().toStringNorm(0));
   
    FileOutputStream fw=new FileOutputStream(modelfile);
    
    ObjectOutputStream os=new ObjectOutputStream(fw);
    os.writeObject(new IGPProgramHolder(gp.getAllTimeBest(),vx1,vx2,vx3,vx4,vx200,vx201,vx202,vx203,vx204));//vx194,vx195,vx196,vx197,vx198,vx199,vx200,vx201,vx202,vx203,vx204));
    os.close();
    
    // Create a graphical tree of the best solution's program and write it to
    // a PNG file.
    // ----------------------------------------------------------------------
    problem.showTree(gp.getAllTimeBest(), "StockProblem_best.png");
    
  }

	public static double movAvg(Stock stock,int start,int days){
		double sum=0;
		for(int i=start;i<start+days;i++){
			sum+=stock.getPrices().get(i);
		}
		return sum/days;
	}
  /**
   * Fitness function for evaluating the produced fomulas, represented as GP
   * programs. The fitness is computed by calculating the result (Y) of the
   * function/formula for integer inputs 0 to 20 (X). The sum of the differences
   * between expected Y and actual Y is the fitness, the lower the better (as
   * it is a defect rate here).
   */
  public static class FormulaFitnessFunction
      extends GPFitnessFunction {
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;


	protected double evaluate(final IGPProgram a_subject) {
      return computeRawFitness(a_subject);
    // return 6;
    }

    public double computeRawFitness(final IGPProgram ind) {
    	
    	double sum=0;
    	for(Stock s:stocks){
    		Object[] noargs = new Object[0];
    		ArrayList<Double> prices=s.getPrices();
    		for(int i=0;i<=300-days-1;i+=100){
    			vx1.set(movAvg(s,i+200-days,days));
        		vx2.set(movAvg(s,i+200-days-50,days));
        		vx3.set(movAvg(s,i+200-days-100,days));
        		vx4.set(movAvg(s,i+200-days-150,days));
        		
        		//vx5.set(s.getPrices().get(i));
        		//vx6.set(s.getPrices().get(i+1));
        		/*vx7.set(s.getPrices().get(i+2));
        		vx8.set(s.getPrices().get(i+3));
        		vx9.set(s.getPrices().get(i+4));
        		vx10.set(s.getPrices().get(i+5));
        		vx11.set(s.getPrices().get(i+6));
        		vx12.set(s.getPrices().get(i+7));
        		vx13.set(s.getPrices().get(i+8));
        		vx14.set(s.getPrices().get(i+9));
        		vx15.set(s.getPrices().get(i+10));
        		vx16.set(s.getPrices().get(i+11));
        		vx17.set(s.getPrices().get(i+12));
        		vx18.set(s.getPrices().get(i+13));
        		vx19.set(s.getPrices().get(i+14));
        		vx20.set(s.getPrices().get(i+15));
        		vx21.set(s.getPrices().get(i+16));
        		vx22.set(s.getPrices().get(i+17));
        		vx23.set(s.getPrices().get(i+18));
        		vx24.set(s.getPrices().get(i+19));
        		vx25.set(s.getPrices().get(i+20));
        		vx26.set(s.getPrices().get(i+21));
        		vx27.set(s.getPrices().get(i+22));
        		vx28.set(s.getPrices().get(i+23));
        		vx29.set(s.getPrices().get(i+24));
        		vx30.set(s.getPrices().get(i+25));
        		vx31.set(s.getPrices().get(i+26));
        		vx32.set(s.getPrices().get(i+27));
        		vx33.set(s.getPrices().get(i+28));
        		vx34.set(s.getPrices().get(i+29));
        		vx35.set(s.getPrices().get(i+30));
        		vx36.set(s.getPrices().get(i+31));
        		vx37.set(s.getPrices().get(i+32));
        		vx38.set(s.getPrices().get(i+33));
        		vx39.set(s.getPrices().get(i+34));
        		vx40.set(s.getPrices().get(i+35));
        		vx41.set(s.getPrices().get(i+36));
        		vx42.set(s.getPrices().get(i+37));
        		vx43.set(s.getPrices().get(i+38));
        		vx44.set(s.getPrices().get(i+39));
        		vx45.set(s.getPrices().get(i+40));
        		vx46.set(s.getPrices().get(i+41));
        		vx47.set(s.getPrices().get(i+42));
        		vx48.set(s.getPrices().get(i+43));
        		vx49.set(s.getPrices().get(i+44));
        		vx50.set(s.getPrices().get(i+45));
        		vx51.set(s.getPrices().get(i+46));
        		vx52.set(s.getPrices().get(i+47));
        		vx53.set(s.getPrices().get(i+48));
        		vx54.set(s.getPrices().get(i+49));
        		vx55.set(s.getPrices().get(i+50));
        		vx56.set(s.getPrices().get(i+51));
        		vx57.set(s.getPrices().get(i+52));
        		vx58.set(s.getPrices().get(i+53));
        		vx59.set(s.getPrices().get(i+54));
        		vx60.set(s.getPrices().get(i+55));
        		vx61.set(s.getPrices().get(i+56));
        		vx62.set(s.getPrices().get(i+57));
        		vx63.set(s.getPrices().get(i+58));
        		vx64.set(s.getPrices().get(i+59));
        		vx65.set(s.getPrices().get(i+60));
        		vx66.set(s.getPrices().get(i+61));
        		vx67.set(s.getPrices().get(i+62));
        		vx68.set(s.getPrices().get(i+63));
        		vx69.set(s.getPrices().get(i+64));
        		vx70.set(s.getPrices().get(i+65));
        		vx71.set(s.getPrices().get(i+66));
        		vx72.set(s.getPrices().get(i+67));
        		vx73.set(s.getPrices().get(i+68));
        		vx74.set(s.getPrices().get(i+69));
        		vx75.set(s.getPrices().get(i+70));
        		vx76.set(s.getPrices().get(i+71));
        		vx77.set(s.getPrices().get(i+72));
        		vx78.set(s.getPrices().get(i+73));
        		vx79.set(s.getPrices().get(i+74));
        		vx80.set(s.getPrices().get(i+75));
        		vx81.set(s.getPrices().get(i+76));
        		vx82.set(s.getPrices().get(i+77));
        		vx83.set(s.getPrices().get(i+78));
        		vx84.set(s.getPrices().get(i+79));
        		vx85.set(s.getPrices().get(i+80));
        		vx86.set(s.getPrices().get(i+81));
        		vx87.set(s.getPrices().get(i+82));
        		vx88.set(s.getPrices().get(i+83));
        		vx89.set(s.getPrices().get(i+84));
        		vx90.set(s.getPrices().get(i+85));
        		vx91.set(s.getPrices().get(i+86));
        		vx92.set(s.getPrices().get(i+87));
        		vx93.set(s.getPrices().get(i+88));
        		vx94.set(s.getPrices().get(i+89));
        		vx95.set(s.getPrices().get(i+90));
        		vx96.set(s.getPrices().get(i+91));
        		vx97.set(s.getPrices().get(i+92));
        		vx98.set(s.getPrices().get(i+93));
        		vx99.set(s.getPrices().get(i+94));
        		vx100.set(s.getPrices().get(i+95));
        		vx101.set(s.getPrices().get(i+96));
        		vx102.set(s.getPrices().get(i+97));
        		vx103.set(s.getPrices().get(i+98));
        		vx104.set(s.getPrices().get(i+99));
        		vx105.set(s.getPrices().get(i+100));
        		vx106.set(s.getPrices().get(i+101));
        		vx107.set(s.getPrices().get(i+102));
        		vx108.set(s.getPrices().get(i+103));
        		vx109.set(s.getPrices().get(i+104));
        		vx110.set(s.getPrices().get(i+105));
        		vx111.set(s.getPrices().get(i+106));
        		vx112.set(s.getPrices().get(i+107));
        		vx113.set(s.getPrices().get(i+108));
        		vx114.set(s.getPrices().get(i+109));
        		vx115.set(s.getPrices().get(i+110));
        		vx116.set(s.getPrices().get(i+111));
        		vx117.set(s.getPrices().get(i+112));
        		vx118.set(s.getPrices().get(i+113));
        		vx119.set(s.getPrices().get(i+114));
        		vx120.set(s.getPrices().get(i+115));
        		vx121.set(s.getPrices().get(i+116));
        		vx122.set(s.getPrices().get(i+117));
        		vx123.set(s.getPrices().get(i+118));
        		vx124.set(s.getPrices().get(i+119));
        		vx125.set(s.getPrices().get(i+120));
        		vx126.set(s.getPrices().get(i+121));
        		vx127.set(s.getPrices().get(i+122));
        		vx128.set(s.getPrices().get(i+123));
        		vx129.set(s.getPrices().get(i+124));
        		vx130.set(s.getPrices().get(i+125));
        		vx131.set(s.getPrices().get(i+126));
        		vx132.set(s.getPrices().get(i+127));
        		vx133.set(s.getPrices().get(i+128));
        		vx134.set(s.getPrices().get(i+129));
        		vx135.set(s.getPrices().get(i+130));
        		vx136.set(s.getPrices().get(i+131));
        		vx137.set(s.getPrices().get(i+132));
        		vx138.set(s.getPrices().get(i+133));
        		vx139.set(s.getPrices().get(i+134));
        		vx140.set(s.getPrices().get(i+135));
        		vx141.set(s.getPrices().get(i+136));
        		vx142.set(s.getPrices().get(i+137));
        		vx143.set(s.getPrices().get(i+138));
        		vx144.set(s.getPrices().get(i+139));
        		vx145.set(s.getPrices().get(i+140));
        		vx146.set(s.getPrices().get(i+141));
        		vx147.set(s.getPrices().get(i+142));
        		vx148.set(s.getPrices().get(i+143));
        		vx149.set(s.getPrices().get(i+144));
        		vx150.set(s.getPrices().get(i+145));
        		vx151.set(s.getPrices().get(i+146));
        		vx152.set(s.getPrices().get(i+147));
        		vx153.set(s.getPrices().get(i+148));
        		vx154.set(s.getPrices().get(i+149));
        		vx155.set(s.getPrices().get(i+150));
        		vx156.set(s.getPrices().get(i+151));
        		vx157.set(s.getPrices().get(i+152));
        		vx158.set(s.getPrices().get(i+153));
        		vx159.set(s.getPrices().get(i+154));
        		vx160.set(s.getPrices().get(i+155));
        		vx161.set(s.getPrices().get(i+156));
        		vx162.set(s.getPrices().get(i+157));
        		vx163.set(s.getPrices().get(i+158));
        		vx164.set(s.getPrices().get(i+159));
        		vx165.set(s.getPrices().get(i+160));
        		vx166.set(s.getPrices().get(i+161));
        		vx167.set(s.getPrices().get(i+162));
        		vx168.set(s.getPrices().get(i+163));
        		vx169.set(s.getPrices().get(i+164));
        		vx170.set(s.getPrices().get(i+165));
        		vx171.set(s.getPrices().get(i+166));
        		vx172.set(s.getPrices().get(i+167));
        		vx173.set(s.getPrices().get(i+168));
        		vx174.set(s.getPrices().get(i+169));
        		vx175.set(s.getPrices().get(i+170));
        		vx176.set(s.getPrices().get(i+171));
        		vx177.set(s.getPrices().get(i+172));
        		vx178.set(s.getPrices().get(i+173));
        		vx179.set(s.getPrices().get(i+174));
        		vx180.set(s.getPrices().get(i+175));
        		vx181.set(s.getPrices().get(i+176));
        		vx182.set(s.getPrices().get(i+177));
        		vx183.set(s.getPrices().get(i+178));
        		vx184.set(s.getPrices().get(i+179));
        		vx185.set(s.getPrices().get(i+180));
        		vx186.set(s.getPrices().get(i+181));
        		vx187.set(s.getPrices().get(i+182));
        		vx188.set(s.getPrices().get(i+183));
        		vx189.set(s.getPrices().get(i+184));
        		vx190.set(s.getPrices().get(i+185));
        		vx191.set(s.getPrices().get(i+186));
        		vx192.set(s.getPrices().get(i+187));
        		vx193.set(s.getPrices().get(i+188));
        		
        		vx194.set(s.getPrices().get(i+189));
        		vx195.set(s.getPrices().get(i+190));
        		vx196.set(s.getPrices().get(i+191));
        		vx197.set(s.getPrices().get(i+192));
        		vx198.set(s.getPrices().get(i+193));
        		vx199.set(s.getPrices().get(i+194));*/
        		vx200.set(s.getPrices().get(i+195));
        		vx201.set(s.getPrices().get(i+196));
        		vx202.set(s.getPrices().get(i+197));
        		vx203.set(s.getPrices().get(i+198));
        		vx204.set(s.getPrices().get(i+199));
        		
        		double result = ind.execute_double(0, noargs);
        		if(Double.isNaN(result) || Double.isInfinite(result))
        			return 20000;
        		//System.out.println("formula "+ind.toStringNorm(0));
        		//System.out.println("wanted price "+prices.get(i+200+days));
        		//System.out.println("result "+result);
        		sum+=Math.abs(result-prices.get(i+200+days));
    		}
    	}
    	return sum;
      /*double error = 0.0f;
      Object[] noargs = new Object[0];
      // Evaluate function for input numbers 0 to 20.
      // --------------------------------------------
      for (int i = 0; i < 20; i++) {
        // Provide the variable X with the input number.
        // See method create(), declaration of "nodeSets" for where X is
        // defined.
         * 
         * 
         * 
        // -------------------------------------------------------------
        vx.set(x[i]);
        try {
          // Execute the GP program representing the function to be evolved.
          // As in method create(), the return type is declared as double (see
          // declaration of array "types").
          // ----------------------------------------------------------------
          double result = ind.execute_double(0, noargs);
          // Sum up the error between actual and expected result to get a defect
          // rate.
          // -------------------------------------------------------------------
          error += Math.abs(result - y[i]);
          // If the error is too high, stop evlauation and return worst error
          // possible.
          // ----------------------------------------------------------------
          if (Double.isInfinite(error)) {
            return Double.MAX_VALUE;
          }
        } catch (ArithmeticException ex) {
          // This should not happen, some illegal operation was executed.
          // ------------------------------------------------------------
          System.out.println("x = " + x[i].doubleValue());
          System.out.println(ind);
          throw ex;
        }
      }
      // In case the error is small enough, consider it perfect.
      // -------------------------------------------------------
      if (error < 0.001) {
        error = 0.0d;
      }
      return error;*/
    }
  }
}